package me.ingxin.android.permission2.request

import android.content.Intent
import android.net.Uri
import android.os.Bundle
import android.provider.Settings
import android.util.Log
import androidx.activity.result.contract.ActivityResultContracts
import androidx.fragment.app.Fragment

/**
 * Created on 2023/7/3 by yin
 * 请求权限fragment
 */
class RequestNormalFragment : Fragment() {

    @Suppress("PrivatePropertyName")
    private val TAG = "RequestFragment"

    private lateinit var permissionType: PermissionType
    private lateinit var normalPermissions: List<String>
    private lateinit var normalCallback: (grantedList: List<String>, deniedList: List<String>, notShownList: List<String>) -> Unit
    private lateinit var settingsCallback: () -> Unit

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        if (!this::permissionType.isInitialized) {
            Log.e(TAG, "permissionType not init, will removeSelf")
            removeSelf()
            return
        }

        when (permissionType) {
            //请求常规权限
            PermissionType.Normal -> {
                if (this::normalPermissions.isInitialized && this::normalCallback.isInitialized) {
                    tryRequestNormalPermissions(normalPermissions, normalCallback)
                } else {
                    Log.e(TAG, "normalPermissions not init, will removeSelf")
                    removeSelf()
                }
            }

            //前往设置中心开启常规权限
            PermissionType.NormalToSettings -> {
                if (this::settingsCallback.isInitialized) {
                    tryToSettings(settingsCallback)
                } else {
                    Log.e(TAG, "settingsCallback not init, will removeSelf")
                    removeSelf()
                }
            }
        }
    }

    private fun tryToSettings(callback: () -> Unit) {
        val launcher =
            registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {
                removeSelf()
                callback()
            }
        launcher.launch(Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS).apply {
            data = Uri.fromParts("package", requireContext().packageName, null)
        })
    }

    /**
     * 申请普通权限
     */
    private fun tryRequestNormalPermissions(
        permissions: List<String>,
        callback: (grantedList: List<String>, deniedList: List<String>, notShownList: List<String>) -> Unit
    ) {
        //本次必会显示系统申请框的权限标记为true
        val shouldMap = HashMap<String, Boolean>()
        permissions.forEach {
            //shouldShowRequestPermissionRationale为true表示应该向用户解释申请理由
            // 得出结论--本次系统弹权限弹框会显示
            val shouldShow = shouldShowRequestPermissionRationale(it)
            shouldMap[it] = shouldShow
            if (shouldShow) {
                //本次会显示系统权限弹窗
                Log.d(TAG, "request permission after the first rejection -- $it")
            }
        }
        val launcher =
            registerForActivityResult(ActivityResultContracts.RequestMultiplePermissions()) { grantResults ->
                removeSelf()
                val grantedPermissions = ArrayList<String>()
                val deniedPermissions = ArrayList<String>()
                val notShownList = ArrayList<String>()
                onMultiplePermissions(
                    grantResults, grantedPermissions, deniedPermissions, notShownList, shouldMap
                )
                callback(grantedPermissions, deniedPermissions, notShownList)
            }
        launcher.launch(permissions.toTypedArray())
    }

    /**
     * @param shouldMap map中value为true表示该权限在本次申请前已经申请过一次
     */
    private fun onMultiplePermissions(
        grantResults: Map<String, Boolean>,
        grantedPermissions: MutableList<String>,
        deniedPermissions: MutableList<String>,
        notShownList: MutableList<String>,
        shouldMap: Map<String, Boolean>
    ) {
        for ((permission, granted) in grantResults) {
            if (granted) {
                grantedPermissions.add(permission)
                continue
            }
            val shouldShow = shouldShowRequestPermissionRationale(permission)
            if (shouldShow) {
                //本次是该权限第1次申请且被拒绝了,本次显示了系统权限弹窗
                deniedPermissions.add(permission)
            } else if (shouldMap[permission] == true) {
                //本次显示了系统权限弹窗
                //本次是该权限第被拒绝后再次申请后，再次被拒绝，此次为不在询问，后续申请会直接失败
                deniedPermissions.add(permission)
            } else {
                //本次没有显示系统权限弹窗，需要去设置中心开启
                //本次是该权限被拒2次后再次申请被拒
                notShownList.add(permission)
                Log.d(TAG, "already never ask -- $permission")
            }
        }
    }

    override fun onDestroyView() {
        Log.d(TAG, "requestFragment onDestroyView")
        super.onDestroyView()
    }

    /**
     * 从parentFragmentManager中移除自己
     */
    private fun removeSelf() {
        parentFragmentManager.beginTransaction().remove(this).commitAllowingStateLoss()
    }

    /**
     * 请求常规权限
     * @param permissions 需要申请的权限
     * @param callback 权限回调
     */
    fun requestNormalPermissions(
        permissions: List<String>,
        callback: (grantedList: List<String>, deniedList: List<String>, notShownList: List<String>) -> Unit
    ) {
        permissionType = PermissionType.Normal
        normalPermissions = permissions
        normalCallback = callback
    }

    /**
     * 前往设置中心
     */
    fun requestToSettings(callback: () -> Unit) {
        permissionType = PermissionType.NormalToSettings
        settingsCallback = callback
    }

    /**
     * 请求权限类型
     */
    private enum class PermissionType {
        /**常规权限*/
        Normal,

        /**常规权限不在询问时前往设置*/
        NormalToSettings,
    }

}